<!--
* @author luguoxiang
* @date 2021-09-07
* 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <span v-html="style"></span>
  <lg-form
    ref="formRef"
    class="lg-search-bar"
    :class="key"
    :schema="options"
    :data="data"
    :grid-props="gridPropsInner"
    :col-props="{ class: 'lg-search-item' }"
    v-bind="$attrs"
    @keyup.enter="search"
  >
    <template v-for="(x, key) in $slots" #[key]="scope">
      <slot :name="key" v-bind="scope"></slot>
    </template>
    <template #append>
      <div class="lg-search-item lg-search-bar-action" :class="extendClass">
        <t-button class="gl-btn-search" theme="primary" @click="search">
          <template #icon><search-icon /></template>查询
        </t-button>
        <t-button class="gl-btn-reset" theme="danger" @click="reset">
          <template #icon><rollback-icon /></template>重置
        </t-button>
        <template v-if="columnCount <= options.length">
          <t-link
            v-if="expanded"
            class="lsb-expand-btn lsb-expand-up"
            theme="primary"
            hover="color"
            @click="changeExpand(false)"
          >
            <template #suffix-icon><chevron-up-icon /></template>
            收起
          </t-link>
          <t-link
            v-else
            class="lsb-expand-btn lsb-expand-down"
            theme="primary"
            hover="color"
            @click="changeExpand(true)"
          >
            <template #suffix-icon><chevron-down-icon /></template>
            展开
          </t-link>
        </template>
      </div>
    </template>
  </lg-form>
</template>

<script lang="ts" setup>
import { RollbackIcon, SearchIcon, ChevronUpIcon, ChevronDownIcon } from 'tdesign-icons-vue-next';
import { computed, onMounted, ref, watch } from 'vue';
import { FilterTypeEnum, IConfigSchema, ISearchSchema, LgForm, Map, nextId } from '@/soar';
import { LgGridProps, LgSearchBarProps } from '../types';
import { getSearchs } from './utils';

interface Props<T> extends LgSearchBarProps<T> {
  /**
   * 表单配置
   */
  schema: ISearchSchema<T>[] | IConfigSchema<T>[];
  /**
   * 宫格配置
   */
  gridProps?: LgGridProps;
  /**
   * 自动去空格
   */
  autoTrim?: boolean;
}

const emit = defineEmits(['slotChange', 'search', 'reset']);
const props = withDefaults(defineProps<Props<unknown>>(), {
  gridProps: {
    width: 375,
    gap: [12, 24],
  },
});
const key = `lg-search-bar-${nextId()}`;
const formRef = ref();
const data = ref({});
// 查询配置
let queryConfig: any = {};
// 列总数
const columnCount = ref(0);
// 是否展开
const expanded = ref(false);
// 宫格配置
// 控制显示数量
const style = ref('');
function updateShowCount() {
  if (expanded.value) {
    // 显示全部
    style.value = '';
    return;
  }
  // 计算显示数量
  let count = columnCount.value - 1;
  if (count < 1) {
    count = 1;
  }
  style.value = `
      <style>.${key} .lg-search-item:nth-child(${count})~.lg-search-item:not(.lg-search-bar-action) {display: none;}</style>
    `;
}
const gridPropsInner = computed(() => {
  return {
    ...props.gridProps,
    onChange(e: any) {
      columnCount.value = e;
      updateShowCount();
    },
  };
});
// 展开的类名
const extendClass = computed(() => (expanded.value || columnCount.value === 1 ? 'lg-search-bar-expanded' : ''));
// 表单配置
const options = computed(() => {
  const list: any[] = getSearchs(props.schema);
  // 搜索框插槽
  const searchSlots: any = [];
  // 处理搜索框配置
  const qc: any = {};
  for (const search of list) {
    const { slots } = search;
    for (const slotsKey in slots) {
      searchSlots.push(slots[slotsKey]);
    }
    if (search.searchType === FilterTypeEnum.CUSTOM) {
      qc[search.field] = search.field;
    } else {
      qc[search.field] = `${search.field}-${search.searchType || FilterTypeEnum.LIKE}`;
    }
  }
  emit('slotChange', searchSlots);
  queryConfig = qc;
  return list;
});
// 展开事件
function changeExpand(e: boolean) {
  expanded.value = e;
  updateShowCount();
}
watch(() => options.value.length, updateShowCount);
// 获取参数
function getSoarQuery(data: any) {
  const soarQuery: any = {};
  for (const field in data) {
    soarQuery[queryConfig[field]] = data[field];
  }
  return soarQuery;
}
// 搜索事件
function search(): void {
  return formRef.value.validate().then((values: Map<any>) => {
    if (props.autoTrim) {
      for (const k in values) {
        const x = values[k];
        if (typeof x === 'string') {
          values[k] = x.trim();
        }
      }
    }
    emit('search', values, getSoarQuery(values));
    return values;
  });
}

// 重置事件
function reset(): void {
  formRef.value.reset();
  return formRef.value.validate().then((values: Map<any>) => {
    emit('reset', values, getSoarQuery(values));
    return values;
  });
}

onMounted(updateShowCount);
// 对外暴露的api
defineExpose({
  formRef,
  search,
  reset,
});
</script>
<script lang="ts">
export default {
  name: 'LgSearchBar',
};
</script>

<style lang="less" scoped>
.lg-search-bar {
  background-color: var(--app-color-bg-primary);
  border-radius: var(--app-border-radius);
  padding: var(--app-space);
  .lg-search-bar-action {
    display: flex;
  }
  .lg-search-item.lg-search-bar-action.lg-search-bar-expanded {
    max-width: 100%;
    justify-content: flex-end;
  }
  .lsb-expand-btn {
    height: var(--app-height-component);
    margin-left: var(--td-comp-margin-s);
  }
  .lsb-expand-up {
  }
  .lsb-expand-down {
  }
}
</style>
